
// ===============================================================================================================
// -*- C++ -*-
//
// Thread.hpp - Declaration of a Thread wrapper class and mutex object.
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#ifndef __THREADS_HPP__
#define __THREADS_HPP__

#ifdef _MSC_VER
#include <process.h>
#else
#include <pthread.h>
#endif

typedef void (* ThreadFunc)(void * userData);

// Simple thread wrapper that supports Win32 Threads
// and POSIX PThreads.
class Thread {

public:

	// Creates and executes a new thread.
	Thread(ThreadFunc fn, void * ud);

	// Wait for the thread to finish execution.
	void join(void);

	 ~Thread(void);

private:

	// Disallow copy and assignment
	Thread(const Thread &);
	Thread & operator = (const Thread &);

#ifdef _MSC_VER
	void * threadHandle;
	static unsigned int __stdcall MyThreadProc(void * ctx);
#else
	pthread_t threadHandle;
	static void * MyThreadProc(void * ctx);
#endif

	// Pointer to user code to be executed.
	ThreadFunc userFunc;

	// Pointer to a user defined data to be passed to the thread.
	void * userData;
};

// Mutual exclusion lock (mutex)
class Mutex {

public:

    Mutex(void);
    ~Mutex(void);

    // Lock the mutex object.
	void Lock(void) const;

	// Unlock the mutex for other threads.
    void Unlock(void) const;

private:

	// Disallow copy and assignment
	Mutex(const Mutex &);
	Mutex & operator = (const Mutex &);

#if _MSC_VER
    // Wraper class for the Win32 critical sections.
    mutable CRITICAL_SECTION critSect;
#else
	mutable pthread_mutex_t mtx;
#endif
};

#endif // __THREADS_HPP__
